package com.devunion.bogdan.view.util;

import com.devunion.bogdan.view.project.dialogs.ActionResult;

import javax.swing.*;
import javax.swing.border.MatteBorder;
import java.awt.*;
import java.awt.event.ActionEvent;

/**
 * User: Leska
 * Date: 07.01.2003
 * Time: 13:41:32
 */
public class ComponentFactory {

    public static JComponent getHR() {
        JPanel horizontalGlue = new JPanel();
        horizontalGlue.setSize(new Dimension(1, 2));
        horizontalGlue.setPreferredSize(new Dimension(1, 2));
        horizontalGlue.setMaximumSize(new Dimension(1, 2));

        horizontalGlue.setBorder(BorderFactory.createCompoundBorder(
                new MatteBorder(1, 0, 0, 0, horizontalGlue.getBackground().darker()),
                new MatteBorder(0, 0, 1, 0, horizontalGlue.getBackground().brighter())));
        return horizontalGlue;
    }

    public static OkCancelPanel createPanelButtonOkCancel(final JDialog parentWindow, ActionHandler okActionHandler, ActionValidator okActionValidator) {
        return createPanelButtonOkCancel(
                parentWindow,
                OkCancelPanel.Layout.HORIZONTAL,
                okActionHandler, okActionValidator);
    }

    public static OkCancelPanel createPanelButtonOkCancel(final JDialog parentWindow, ActionHandler okActionHandler, ActionHandler cancelActionHandler, ActionValidator okActionValidator) {
        return createPanelButtonOkCancel(
                parentWindow,
                OkCancelPanel.Layout.HORIZONTAL,
                okActionHandler, cancelActionHandler, okActionValidator);
    }

    public static OkCancelPanel createPanelButtonOkCancel(final JDialog parentWindow, OkCancelPanel.Layout layout, ActionHandler okActionHandler, ActionValidator okActionValidator) {
        ActionHandler cancelActionHandler = new ActionHandler() {
            public void execute() {
                parentWindow.setVisible(false);
            }
        };

        return createPanelButtonOkCancel(
                parentWindow,
                layout,
                okActionHandler, okActionValidator,
                cancelActionHandler, null);
    }

    public static OkCancelPanel createPanelButtonOkCancel(final JDialog parentWindow, OkCancelPanel.Layout layout, ActionHandler okActionHandler, ActionHandler cancelActionHandler, ActionValidator okActionValidator) {
        return createPanelButtonOkCancel(
                parentWindow,
                layout,
                okActionHandler, okActionValidator,
                cancelActionHandler, null);
    }

    public static OkCancelPanel createPanelButtonOkCancel(final JDialog parentWindow, OkCancelPanel.Layout layout,
                                                          ActionHandler okActionHandler, ActionValidator okActionValidator,
                                                          ActionHandler cancelActionHandler, ActionValidator cancelActionValidator) {

        return new OkCancelPanel(parentWindow, layout, okActionHandler, okActionValidator, cancelActionHandler, cancelActionValidator);
    }


    public static class OkCancelPanel extends JPanel {
        private JButton jButtonOk;
        private JButton jButtonCancel;

        private ActionResult actionResult;

        public OkCancelPanel(final JDialog parentWindow,
                             ActionHandler okActionHandler, ActionValidator okActionValidator,
                             ActionHandler cancelActionHandler, ActionValidator cancelActionValidator) {

            this(parentWindow,
                    Layout.HORIZONTAL,
                    okActionHandler, okActionValidator,
                    cancelActionHandler, cancelActionValidator
            );
        }

        public OkCancelPanel(final JDialog parentWindow,
                             Layout layout,
                             ActionHandler okActionHandler, ActionValidator okActionValidator,
                             ActionHandler cancelActionHandler, ActionValidator cancelActionValidator) {

            if (layout == Layout.HORIZONTAL) {
                setLayout(new FlowLayout(FlowLayout.CENTER));
            } else {
                setLayout(new GridLayout(2, 1, 5, 5));
            }

            AbstractAction actionOk = createAction("Ok",
                    okActionHandler,
                    okActionValidator,
                    ActionResult.OK
            );

            AbstractAction actionCancel = createAction("Cancel",
                    cancelActionHandler,
                    cancelActionValidator,
                    ActionResult.CANCEL
            );

            add(jButtonOk = new JButton(actionOk));
            add(jButtonCancel = new JButton(actionCancel));

            DialogHelper.setOkKeyboardAction(parentWindow, actionOk);
            DialogHelper.setCancelKeyboardAction(parentWindow, actionCancel);

            parentWindow.getRootPane().setDefaultButton(jButtonOk);
        }

        private AbstractAction createAction(String msg, ActionHandler okActionHandler, ActionValidator okActionValidator, final ActionResult result) {
            DialogAction res = new DialogAction(i18n.getString(msg)) {

                public void actionPerformed(ActionEvent e) {
                    super.actionPerformed(e);

                    actionResult = result;
                }
            };

            res.setActionHandler(okActionHandler);
            res.setValidator(okActionValidator);

            return res;
        }

        public JButton getButtonOk() {
            return jButtonOk;
        }

        public JButton getButtonCancel() {
            return jButtonCancel;
        }

        public ActionResult getActionResult() {
            return actionResult;
        }

        public enum Layout {
            HORIZONTAL, VERTICAL
        }
    }

    public interface ActionHandler {
        public void execute();
    }

    public interface ActionValidator {
        public boolean validate();
    }

    private static class DialogAction extends AbstractAction {
        private ActionHandler actionHandler;
        private ActionValidator validator;

        public DialogAction(String name) {
            super(name);
        }

        public void setActionHandler(ActionHandler actionHandler) {
            this.actionHandler = actionHandler;
        }

        public void setValidator(ActionValidator validator) {
            this.validator = validator;
        }

        public void actionPerformed(ActionEvent e) {

            if (validator != null && !validator.validate()) {
                return;
            }

            if (actionHandler != null) {
                actionHandler.execute();
            }
        }
    }
}
